/**
 * Copyright 2010 Victor Egea Hernando
 *
 * RockScript is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 * 
 * RockScript is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with RockScript.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "vmclass.h"

namespace paper {

typedef struct vm_class::core {
	// maps
	__attribute_map _attribute_map;
	__method_map _method_map;
	// vectors
	std::vector<method*> _method;
	// another references
	corelib::ustring _name;
	corelib::uint32 _idx;
	__register _single;

};

method* vm_class::get_method(corelib::uint32 idx) {
	return _core->_method[idx];
}

corelib::uint32 vm_class::msize(void) const {
	return _core->_method.size();
}

const corelib::ustring &vm_class::name(void) const {
	return _core->_name;
}

corelib::uint32 vm_class::idx(void) const {
	return _core->_idx;
}

__register &vm_class::single( void ){
	return _core->_single;
}

vm_class::vm_class(const corelib::ustring &name, corelib::uint32 idx) {
	_core = new core;
	// assign values to the core
	_core->_name = name;
	_core->_idx = idx;
}

vm_class::~vm_class() {
	for (corelib::uint32 it = 0; it < _core->_method.size(); it++) {
		// delete method object
		delete _core->_method[it];
	}
	delete _core;
}

corelib::pair<method*, bool> vm_class::add_method(const corelib::ustring &name,
		const corelib::ustring &meta, corelib::uint32 nargs) {
	// create new method
	method *m = new method(name, this, _core->_method.size(), meta, nargs);
	// insert method index if possible
	corelib::pair<__method_map ::iterator, bool> res = _core->_method_map.insert(
			__method_map::pair_t(m, _core->_method.size()));

	// create a new method
	if ( res.second ) {
		// push method
		_core->_method.push_back(m);
		// return method
		return corelib::pair<method*, bool>(m, true);
	}

	// delete new method
	delete m;
	// return old method
	return corelib::pair<method*, bool>(_core->_method[res.first->second], false);
}

bool vm_class::get_method_idx(const corelib::ustring &meta_name,
		corelib::uint32 &idx) {
	// create an instance
	__method_map ::iterator res = _core->_method_map.find(
			&method(meta_name, corelib::null, 0));
	// find method
	if (res == _core->_method_map.end()) {
		return false;
	}
	// return method index
	idx = (*res).second;
	return true;
}

}
;
// namespace paper;
